[quote='800626022, DTS Engineer, /thread/762250?answerId=800626022#800626022']
First off, are you sure you actually want a "NSDockTilePlugin"? NSDockTilePlugin is specifically how an app that ISN'T running can update it's dock icon
[/quote]
Hi Kevin. No I'm not sure but… what I want to provide for my app is a context menu on the dock icon that shows the last 10(?) folder URLs that were browsed from the app - just as Xcode shows the latest projects without having to open Xcode.
[quote='800626022, DTS Engineer, /thread/762250?answerId=800626022#800626022']
Finally, on the menu side, dock menus are actually handled through the applicationDockMenu() delegate method.
[/quote]
I tried this but it didn't show the menu before the app was running.
This is what I want, but with the list instead of just one and before the app has started. This seems to automatically take the title bar caption, which I set to a representative text of the URL.
If NSDockTilePlugin is "deprecated", where can I find how to implement this "app extension" that you mention?
Have I explained myself clearly enough? If not, please let me know.
This is for an app that has been out there for several years and I just got a user request.
Post
Replies
Boosts
Views
Activity
Well, since nobody else seems to be able to answer this question, I will do it myself…
It turns out I was using the wrong QLThumbnailGenerator.
override func prepareForReuse()
{
super.prepareForReuse()
if let request = self.request
{
thumbnailGenerator.cancel(request)
self.request = nil
}
imageView?.image = NSImage(imageLiteralResourceName: "Placeholder")
The problem was so subtle. One thing I didn't quote in my original post was that I had a var that holds a private QLThumbnailGenerator instance and it was this that I was using to cancel the request, even though I was using the shared instance in the loadImage method.
As soon as I switched the loadImage method to use the private var, everything started to work better.
I say better because there was still the occasion when the generator would return a nil image for some obscure reason.
So, for those times, I have a helper method that loads those thumbnails the "old fashioned" way…
static func previewOfFile(at url: URL, size: NSSize, asIcon: Bool = false, completion: @escaping (NSImage) -> ())
{
let cfUrl = url as CFURL
guard let imageSource = CGImageSourceCreateWithURL(cfUrl, nil),
let image = getImage(for: imageSource, at: url, size: size) else
{
completion(NSWorkspace.shared.icon(forFile: url.path))
return
}
completion(image)
}
… and the full code now reads…
let thumbnailGenerator = QLThumbnailGenerator()
var request: QLThumbnailGenerator.Request?
func loadImage()
{
imageView?.image = NSImage(imageLiteralResourceName: "Placeholder")
request = QLThumbnailGenerator.Request(fileAt: self.url!, size: self.imageSize, scale: 1.0, representationTypes: [.lowQualityThumbnail])
self.thumbnailGenerator.generateRepresentations(for: self.request!)
{
(thumbnail: QLThumbnailRepresentation?, type: QLThumbnailRepresentation.RepresentationType, error: Error?) -> Void in
DispatchQueue.main.async
{
let transition = CATransition()
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
transition.duration = 0.5
self.imageView?.layer?.add(transition, forKey: nil)
self.imageView?.image = thumbnail?.nsImage
if thumbnail?.nsImage == nil
{
DispatchQueue.main.async
{
ThumbnailImage.previewOfFile(at: self.url!, size: self.imageSize)
{
[unowned self] retrievedImage in
transition.duration = 0.3
self.imageView?.image = retrievedImage
}
}
}
I hope this is of use to anyone else who stumbles across this issue
Does nobody have an answer to this question?
Because it crashes if you don't. Something to do with unbalanced calls to resume and suspend apparently.
Thank you Claude for your reply.
When I designed the storyboard, I hadn't added a window controller for each of the segued view controllers and hadn't realised that it would be necessary just to save the position of them.
I have added them and created a NSWindowController subclass to add in the necessary code.